package jmine.tec.hydra.actions.domain;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

import jmine.tec.hydra.api.HydraAction;
import jmine.tec.hydra.api.HydraMessage;
import jmine.tec.hydra.api.HydraSpecification;
import jmine.tec.hydra.domain.actions.AbstractHydraAction;
import jmine.tec.hydra.domain.enumx.HydraActionStatus;
import jmine.tec.persist.annotation.Constraint;
import jmine.tec.persist.annotation.DiscriminatorComment;
import bancosys.tec.component.Documentation;

@Entity
@DiscriminatorValue("42")
@DiscriminatorComment("MOCK")
public class MockAction extends AbstractHydraAction {

    private RuntimeException initializationException;

    private Exception executeException;

    private RuntimeException successException;

    private RuntimeException failureException;

    private HydraActionStatus actionStatus;

    private List<HydraAction> nextActions = new ArrayList<HydraAction>();

    private String actionDescription;

    private Boolean executed = false;

    private HydraMessage message;

    private String conversationIdentification;

    private HydraSpecification specification;

    /**
     * @return the executed
     */
    @Constraint(suffix = "MOCK_JT_0")
    @Column(name = "MOCK_WAS_EXECUTED")
    @Documentation("TABELA DE TESTES.")
    public Boolean getExecuted() {
        return this.executed;
    }

    public void setExecuted(Boolean executed) {
        this.executed = executed;
    }

    /**
     * @param initializationException the initializationException to set
     */
    public void setInitializationException(RuntimeException initializationException) {
        this.initializationException = initializationException;
    }

    /**
     * @param executeException the executeException to set
     */
    public void setExecutionException(Exception executeException) {
        this.executeException = executeException;
    }

    /**
     * @param successException the successException to set
     */
    public void setSuccessException(RuntimeException successException) {
        this.successException = successException;
    }

    /**
     * @param failureException the failureException to set
     */
    public void setFailureException(RuntimeException failureException) {
        this.failureException = failureException;
    }

    /**
     * @param actionStatus the actionStatus to set
     */
    public void setActionStatus(HydraActionStatus actionStatus) {
        this.actionStatus = actionStatus;
    }

    /**
     * @param nextActions the nextActions to set
     */
    public void addNextAction(MockAction action) {
        this.nextActions.add(action);
    }

    /**
     * @param actionDescription the actionDescription to set
     */
    public void setActionDescription(String actionDescription) {
        this.actionDescription = actionDescription;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected String createDescription() {
        return this.actionDescription;
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (this.initializationException != null) {
            throw this.initializationException;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected List<HydraAction> doExecute() throws Exception {
        this.executed = true;
        if (this.executeException != null) {
            throw this.executeException;
        }
        if (this.specification != null) {
            this.setSpecification(this.specification);
        }
        if (this.actionStatus != null) {
            if (this.actionStatus.pending()) {
                super.markAsPending();
            } else {
                this.setStatus(this.actionStatus);
            }
        }
        if (this.message != null) {
            if (this.conversationIdentification == null) {
                this.saveMessage(this.message);
            } else {
                this.saveMessageWithConversation(this.conversationIdentification, this.message);
            }
        }

        return this.nextActions;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onSuccess() {
        super.onSuccess();
        if (this.successException != null) {
            throw this.successException;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onFailure(Throwable t) {
        super.onFailure(t);
        if (this.failureException != null) {
            throw this.failureException;
        }
    }

    /**
     * Define a
     * 
     * @param message
     */
    public void setMessage(HydraMessage message) {
        this.message = message;
    }

    public void setConversationIdentification(String conversationIdentification) {
        this.conversationIdentification = conversationIdentification;
    }

    public void setTestSpecification(HydraSpecification specification) {
        this.specification = specification;
    }
}
